<template>
	<div class="amap-main" :style="style">
		<el-select
			v-model="searchData.keywords"
			filterable
			remote
			reserve-keyword
			placeholder="请输入关键词"
			:remote-method="remoteMethod"
			:loading="searchData.loading"
			:clearable="true"
			size="mini"
			@change="currentSelect"
            class="w-[400px] search-input"
		>
			<el-option v-for="item in searchData.options" :key="item.id" :label="item.name" :value="item" class="one-text">
				<span style="float: left">{{ item.name }}</span>
				<span style="float: right; color: #8492a6; font-size: 13px">{{ item.district }}</span>
			</el-option>
		</el-select>
		<div class="map-container" id="container"></div>
	</div>
</template>
 
<script lang="ts" setup>
import { computed, onMounted, onUnmounted, reactive } from 'vue';
import AMapLoader from '@amap/amap-jsapi-loader';
import { getMapInfo } from '/@/api/setting/webset';
import { messageError } from '/@/utils/message';

const props = defineProps({
	// 初始化数据
	mapData: {
		type: Object,
		default: function () {
			return { lng: '', lat: ''};
		},
	},
	// 长度
	width: {
		type: String,
		default: '100%',
	},
	// 高度
	height: {
		type: String,
		default: '360px',
	},
	// 是否显示比例尺
	isScale: {
		type: Boolean,
		default: true,
	},
	// 是否显示缩放按钮
	isToolBar: {
		type: Boolean,
		default: true,
	},
});

let map = null;

let AMap = null;

let AutoComplete = null;

let marker = null;

const initData = reactive({
    key: '', 
    code: '', 
});

const getInitData = async () => {
    const data = await getMapInfo();
    for (const key in initData) {
		if(data[key] != null && data[key] != undefined) {
			initData[key] = data[key];
		}
    }
	init();
};

const searchData = reactive({
	keywords: '',
	options: [],
	loading: false,
});

const mapDataInfo: any = reactive({
	lng: '',
	lat: '',
	city: '',
	code: '',
	province: '',
	address: '',
});

const emit = defineEmits(['confirm']);

const style = computed(() => {
	return {
		width: props.width,
		height: props.height,
	};
});

const initMap = (plugins) => {
    return new Promise((resolve, reject) => {
        AMapLoader.load({
            "key": initData.key,
            "version": "2.0",
            "plugins": plugins
        }).then((AMap) => {
            resolve(AMap)
        }).catch(err => {
            reject(err)
        })
    })
}

const init = () => {

	window._AMapSecurityConfig = {
		securityJsCode: initData.code,
	}

	initMap(['AMap.Scale', 'AMap.PlaceSearch', 'AMap.AutoComplete', 'AMap.ToolBar', 'AMap.Geocoder'])
		.then((aMap) => {
			AMap = aMap;
			map = new AMap.Map('container', {
				viewMode: '3D', //3D地图模式
				zoom: 15, // 地图级别
				center: [props.mapData.lng, props.mapData.lat], // 中心点位置
			});

			// 添加比例尺
			if (props.isScale) {
				const scale = new AMap.Scale();
				map.addControl(scale);
			}

			// 添加简单的缩放按钮
			if (props.isToolBar) {
				const toolBar = new AMap.ToolBar();
				map.addControl(toolBar);
			}

			AutoComplete = new AMap.AutoComplete();

			mapDataInfo.lng = props.mapData.lng;
			mapDataInfo.lat = props.mapData.lat;

			setMarker();
		})
		.catch((err) => {
			messageError(err);
		});
};

const setDetailAddress = () => {
	// 地址逆解析
	let geoCoder = new AMap.Geocoder({
		city: '全国', //城市，默认：全国
		radius: 1000, //范围，默认：500
	});
	geoCoder.getAddress([mapDataInfo.lng, mapDataInfo.lat], (status, result) => {
		if (status === 'complete' && result.regeocode) {
			mapDataInfo.city = result.regeocode.addressComponent.city;
			mapDataInfo.code = result.regeocode.addressComponent.adcode;
			mapDataInfo.province = result.regeocode.addressComponent.province;
			mapDataInfo.address = result.regeocode.formattedAddress;
			// 兼容城市为空
			if(!mapDataInfo.city) mapDataInfo.city = mapDataInfo.province;
			emit('confirm', mapDataInfo);
		}
	});
};

const remoteMethod = (query) => {
	if (query !== '') {
		searchData.loading = true;
		setTimeout(() => {
			searchData.loading = false;
			AutoComplete.search(query, (status, result) => {
				searchData.options = result.tips;
			});
		}, 200);
	} else {
		searchData.options = [];
	}
};

const currentSelect = (res) => {
	if (!res?.location) return;
	mapDataInfo.lng = res.location.lng;
	mapDataInfo.lat = res.location.lat;
	removeMarker();
	setMarker();
	setDetailAddress();
};

const setMarker = () => {
	marker = new AMap.Marker({
		map: map,
		position: [mapDataInfo.lng, mapDataInfo.lat],
		offset: new AMap.Pixel(-13, -30),
		draggable: true,
		cursor: 'move',
		raiseOnDrag: true,
	});
	map.setFitView(); // 自动适应范围区域
	marker.setMap(map);
	map.setCenter([mapDataInfo.lng, mapDataInfo.lat], true);

	marker.on('dragend', function (e) {
		mapDataInfo.lng = e.lnglat.lng;
		mapDataInfo.lat = e.lnglat.lat;
		setDetailAddress();
	});
};

const removeMarker = () => {
	if (marker) map.remove(marker);
};

onMounted(() => {
	getInitData();
});

onUnmounted(() => {
	map?.destroy();
});
</script>
 
<style lang="scss" scoped>
.amap-main {
	width: 100%;
	position: relative;
	.search-input{
		position: absolute;
		top: 20px;
		left: 20px;
		z-index: 999;
	}
	.map-container {
		padding: 0;
		margin: 0;
		width: 100%;
		height: 100%;
	}
}
</style>